package com.diaohaiwen.common.log;

import com.diaohaiwen.common.enums.LogTypeEnum;
import com.diaohaiwen.common.util.ClassUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.commons.util.SpringFactoryImportSelector;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.AnnotationMetadata;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Set;

import static com.diaohaiwen.common.constant.ConfigurationConstant.*;

/**
 * @author 刁海文
 * @since 2024/1/14 17:59
 */
@Slf4j
@Order(Ordered.LOWEST_PRECEDENCE - 100)
public class SpringLogImportSelector extends SpringFactoryImportSelector<EnableOperatorLog> {


    public String[] selectImports(AnnotationMetadata metadata) {
        String[] imports = super.selectImports(metadata);
        ArrayList<String> list = new ArrayList<>(Arrays.asList(imports));
        Class<BaseLogSend> impl = getLogImpl();
        list.add(impl.getName());
        list.add(LogService.class.getName());
        return list.toArray(new String[0]);
    }


    public Class<BaseLogSend> getLogImpl() {
        LogTypeEnum logType = logType();
        if (logType == null || LogTypeEnum.DEFAULT == logType) {
            log.error("BaseLogSend 未实现其子类");
            return BaseLogSend.class;
        }
        Set<Class<BaseLogSend>> children = ClassUtils.children(BaseLogSend.class, "com.diaohaiwen");
        for (Class<BaseLogSend> child : children) {
            Method method = ClassUtils.getDeclaredMethod(child, "logClassType");
            BaseLogSend baseLogSend = ClassUtils.newInstance(child);
            LogTypeEnum invoke = ClassUtils.methodInvoke(baseLogSend, method);
            if (logType == invoke) {
                return child;
            }
        }
        ClassUtils.scanPackage(PACKAGE_ROOT);
        log.error("BaseLogSend 未实现其子类 [{}],使用默认类：BaseLogSend", logType);
        return BaseLogSend.class;
    }

    @Override
    protected boolean isEnabled() {
        return getEnvironment().getProperty(LOG_ENABLE, Boolean.class, Boolean.TRUE);
    }

    private LogTypeEnum logType() {
        String property = getEnvironment().getProperty(LOG_CLASS_TYPE, String.class);
        if (property == null) {
            return LogTypeEnum.DEFAULT;
        }
        return LogTypeEnum.valueOf(property.toUpperCase());
    }

    @Override
    public boolean hasDefaultFactory() {
        return true;
    }

}
